package com.youlu.campus.common.utils;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author zgz
 * @date 2020/4/9 15:49
 */
@Slf4j
public class ExcelUtil {

    public static <T extends BaseRowModel> List<T> readData(String path, String fileName, Class<T> clazz) {
        String filePath = path + File.separator + fileName;
        Sheet sheet = new Sheet(1, 1, clazz);
        InputStream fileStream = null;
        try {
            fileStream = new FileInputStream(filePath);
            ModelExcelListener<T> excelListener = new ModelExcelListener<>();
            EasyExcelFactory.readBySax(fileStream, sheet, excelListener);
            return excelListener.getDatas();
        } catch (FileNotFoundException e) {
            log.error("找不到文件或文件路径错误, 文件：{}", filePath);
        }finally {
            try {
                if(fileStream != null){
                    fileStream.close();
                }
            } catch (IOException e) {
                log.error("excel文件读取失败, 失败原因：{}", e);
            }
        }
        return Collections.emptyList();
    }

    public static <T extends BaseRowModel> List<T> readData(InputStream inputStream, Class<T> clazz) {
        Sheet sheet = new Sheet(1, 1, clazz);
        try {
            ModelExcelListener<T> excelListener = new ModelExcelListener<>();
            EasyExcelFactory.readBySax(inputStream, sheet, excelListener);
            return excelListener.getDatas();
        } catch (Exception e) {
            log.error("readData error", e);
        }
        return Collections.emptyList();
    }

    public static class ModelExcelListener<E> extends AnalysisEventListener<E> {

        private List<E> datas = new ArrayList<>();

        /**
         * 逐行解析
         * object : 当前行的数据
         */
        @Override
        public void invoke(E model, AnalysisContext context) {
            //当前行
            if (model != null) {
                datas.add(model);
            }
        }


        /**
         * 解析完所有数据后会调用该方法
         */
        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {
            //解析结束销毁不用的资源
        }

        public List<E> getDatas() {
            return datas;
        }

        public void setDatas(List<E> datas) {
            this.datas = datas;
        }
    }
}
